// 相机实体类：控制游戏视角和屏幕震动效果
class Camera extends Entity {
    // 构造函数：初始化相机属性
    constructor() {
        super();
        // 将实体添加到相机分类桶
        this.buckets = ['camera'];

        // 初始化相机边界和震动相关属性
        this.minX = this.minY = this.maxX = this.maxY = 0;
        this.shakeEnd = 0;      // 震动结束时间
        this.nextShake = 0;     // 下一次震动时间
        this.shakePower = 1;    // 震动强度
    }

    // 触发相机震动效果
    // @param power: 震动强度
    shake(power) {
        this.shakePower = power;
        this.shakeEnd = this.age + 0.4; // 震动持续0.4秒
    }

    // 更新相机状态
    // @param elapsed: 距离上一帧的时间间隔
    cycle(elapsed) {
        super.cycle(elapsed);

        // 调整边界确保不小于画布大小
        const width = max(this.maxX - this.minX, CANVAS_WIDTH) / 2;
        const height = max(this.maxY - this.minY, CANVAS_HEIGHT) / 2;
        const midX = (this.maxX + this.minX) / 2;
        const midY = (this.maxY + this.minY) / 2;

        // 更新相机边界
        this.minX = midX - width;
        this.maxX = midX + width;
        this.minY = midY - height;
        this.maxY = midY + height;

        // 获取玩家实体
        const player = firstItem(this.world.bucket('player'));
        if (!player) return;

        // 处理相机震动效果
        this.nextShake -= elapsed;
        if (this.age < this.shakeEnd) {
            if (this.nextShake <= 0) {
                this.nextShake = 1 / 60;  // 每帧更新一次震动
                // 添加随机偏移实现震动效果
                this.x += rnd(-this.shakePower, this.shakePower) * 20;
                this.y += rnd(-this.shakePower, this.shakePower) * 20;
            }
        }

        // 计算目标位置（相对于玩家）
        const targetX = between(
            this.minX + CANVAS_WIDTH / 2,
            player.x + CANVAS_WIDTH / 4,  // 稍微偏向玩家前方
            this.maxX - CANVAS_WIDTH / 2,
        );

        const targetY = between(
            this.minY + CANVAS_HEIGHT / 2,
            player.y,
            this.maxY - CANVAS_HEIGHT / 2,
        );

        // 计算相机移动速度
        const diffX = abs(targetX - this.x);
        const diffY = abs(targetY - this.y);
        const velX = diffX / 0.5;  // 0.5秒内追上目标
        const velY = diffY / 0.5;

        // 平滑移动相机位置
        this.x += between(
            -elapsed * velX,
            targetX - this.x,
            elapsed * velX,
        );
        this.y += between(
            -elapsed * velY,
            targetY - this.y,
            elapsed * velY,
        );

        // 确保相机位置在有效范围内
        this.x = between(
            this.minX + CANVAS_WIDTH / 2,
            this.x,
            this.maxX - CANVAS_WIDTH / 2,
        );

        this.y = between(
            this.minY + CANVAS_HEIGHT / 2,
            this.y,
            this.maxY - CANVAS_HEIGHT / 2,
        );
    }
}
